#include "datawidget.h"

namespace verema
{

DataWidget::DataWidget()
: vbl_mainlayout(this)
, hbl_top()
, hbl_bottom()
, tbl_items(this)
, grb_select("Tabellenauswahl", this)
, grb_filter("Tabellenfilter", this)
, grb_action("Tabellenaktionen", this)
, vbl_select()
, vbl_filter()
, hbl_action()
, vbl_actionLeft()
, vbl_actionRight()
, lbl_unit(&grb_select)
, lbl_subunit(&grb_select)
, cmb_unit(&grb_select)
, cmb_subunit(&grb_select)
, chk_inuse("Besetzte Items anzeigen", &grb_filter)
, chk_notinuse("Nicht besetzte Items anzeigen", &grb_filter)
, btn_newUnit(&grb_action)
, btn_deleteUnit(&grb_action)
, btn_newSubunit(&grb_action)
, btn_deleteSubunit(&grb_action)
, lbl_spacer(&grb_action)
, btn_deleteItem(&grb_action)
, m_intListMode(bothChecked)
, m_dataBase(Config::getInstance()->dbname())
, newUnitDialog()
, newSubunitDialog()
{
// Upperlayout
    vbl_select.addWidget(&lbl_unit);
    vbl_select.addWidget(&cmb_unit);
    vbl_select.addWidget(&lbl_subunit);
    vbl_select.addWidget(&cmb_subunit);

    vbl_filter.addWidget(&chk_inuse);
    vbl_filter.addWidget(&chk_notinuse);

    vbl_actionLeft.addWidget(&btn_newUnit);
    vbl_actionRight.addWidget(&btn_deleteUnit);
    vbl_actionLeft.addWidget(&btn_newSubunit);
    vbl_actionRight.addWidget(&btn_deleteSubunit);

    vbl_actionLeft.addWidget(&lbl_spacer);
    vbl_actionRight.addWidget(&btn_deleteItem);

    hbl_action.addLayout(&vbl_actionLeft);
    hbl_action.addLayout(&vbl_actionRight);

    grb_select.setFixedWidth(200);
    grb_select.setLayout(&vbl_select);

    grb_filter.setFixedWidth(230);
    grb_filter.setLayout(&vbl_filter);

    grb_action.setFixedWidth(310);
    grb_action.setLayout(&hbl_action);

    hbl_top.setSpacing(10);

    hbl_top.addWidget(&grb_select);
    hbl_top.addWidget(&grb_action);
	hbl_top.addWidget(&grb_filter);

    chk_inuse.setCheckState(Qt::Checked);
    chk_notinuse.setCheckState(Qt::Checked);

    QSpacerItem *spi_spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
    hbl_top.addItem(spi_spacer);
// Upperlayout

// Bottomlayout
    hbl_bottom.setSpacing(10);
    hbl_bottom.addWidget(&tbl_items);
// Bottomlayout

    vbl_mainlayout.setSpacing(10);
    vbl_mainlayout.addLayout(&hbl_top);
    vbl_mainlayout.addLayout(&hbl_bottom);

    setLayout(&vbl_mainlayout);

    //Text
	Config* m_config = Config::getInstance();

    QString string(m_config->unit().c_str());
	lbl_unit.setText(string);

	string = m_config->subunit().c_str();
	lbl_subunit.setText(string);

    if (tbl_items.columnCount() < 3)
        tbl_items.setColumnCount(3);

    //Spaltengröße in der Tabelle
    tbl_items.setColumnWidth(0, 200);
    tbl_items.setColumnWidth(1, 100);
    tbl_items.setColumnWidth(2, 250);

	m_fields.append(new QTableWidgetItem());
	m_fields.at(0)->setText("Name");
	tbl_items.setHorizontalHeaderItem(0, m_fields.at(0));

	m_fields.append(new QTableWidgetItem());
	m_fields.at(1)->setText("Besetzt");
	tbl_items.setHorizontalHeaderItem(1, m_fields.at(1));

	m_fields.append(new QTableWidgetItem());
	m_fields.at(2)->setText("Beschreibung");
	tbl_items.setHorizontalHeaderItem(2, m_fields.at(2));

	newUnitDialog.hide();
	newSubunitDialog.hide();

	nameActionButtons();

	m_dataBase.getAllUnits(unit_vector);
	updateUnitCombo(true);

	//Connections
	connect(&cmb_unit, SIGNAL(activated(int)), this, SLOT(unitActivated()));
	connect(&cmb_subunit, SIGNAL(activated(int)), this, SLOT(subunitActivated()));
	connect(&tbl_items, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(itemChanged(QTableWidgetItem*)));
	connect(&chk_inuse, SIGNAL(stateChanged(int)), this, SLOT(chkInuseChanged(int)));
	connect(&chk_notinuse, SIGNAL(stateChanged(int)), this, SLOT(chkNotinuseChanged(int)));
	connect(&btn_newUnit, SIGNAL(clicked()), this, SLOT(addUnit()));
	connect(&btn_deleteUnit, SIGNAL(clicked()), this, SLOT(deleteUnit()));
	connect(&btn_newSubunit, SIGNAL(clicked()), this, SLOT(addSubunit()));
	connect(&btn_deleteSubunit, SIGNAL(clicked()), this, SLOT(deleteSubunit()));
	connect(&btn_deleteItem, SIGNAL(clicked()), this, SLOT(deleteItem()));
	connect(&newUnitDialog, SIGNAL(okClicked()), this, SLOT(appendUnit()));
	connect(&newSubunitDialog, SIGNAL(okClicked()), this, SLOT(appendSubunit()));
}

DataWidget::~DataWidget()
{
	deleteAllTableItems();
}

void DataWidget::unitActivated()
{
	m_dataBase.getAllUnits(unit_vector);

	if(cmb_unit.currentIndex() >= unit_vector.size())
	{
		subunit_vector.clear();
		item_vector.clear();
	}
	else
	{
		m_dataBase.getAllSubunits(subunit_vector, unit_vector.at(cmb_unit.currentIndex()).id());
	}

	deleteAllTableItems();
	tbl_items.setColumnCount(m_fields.size());
	tbl_items.setRowCount(0);


	cmb_subunit.clear();

    if(subunit_vector.size() > 0)
    {
       // cmb_subunit.clear();

        for(std::vector<Subunit>::iterator it = subunit_vector.begin(); it != subunit_vector.end(); ++it)
        {
            cmb_subunit.addItem(it->name().c_str());
        }

        subunitActivated();
    }
}

void DataWidget::subunitActivated()
{
	deleteAllTableItems();

	tbl_items.setColumnCount(m_fields.size());
	tbl_items.setRowCount(0);

	filterItemVector();

	int counter = 0;
	QString usedString;

	for(std::vector<Item>::iterator it = item_vector.begin(); it != item_vector.end(); ++it)
	{
		tbl_items.setRowCount(item_vector.size());

		QTableWidgetItem *name = new QTableWidgetItem(it->name().c_str());
		m_tableItems.append(name);
		tbl_items.setItem(counter,0,name);

		QComboBox *used = new QComboBox(this);
		tbl_items.setCellWidget(counter,1,used);
		connect(used, SIGNAL(currentIndexChanged(int)), this, SLOT(comboChanged(int)));
		m_tableCombos.append(used);
		used->addItem("Ja");
		used->addItem("Nein");
		if(it->used() == true)
		{
			used->setCurrentIndex(0);
		}
		else
		{
			used->setCurrentIndex(1);
		}

		QTableWidgetItem *description = new QTableWidgetItem(it->description().c_str());
		m_tableItems.append(description);
		tbl_items.setItem(counter,2,description);

		counter++;
	}
}

void DataWidget::itemChanged(QTableWidgetItem *item)
{
	//Index des geänderten Items suchen
	QTableWidgetItem *temp;
	int result = -1;
	for(int counter = 0; counter < m_tableItems.size(); counter++)
	{
		temp = m_tableItems.at(counter);
		if(temp == item)
		{
			result = counter;
		}
	}

	// In der Liste (m_tableItems) sind Namens- und Description Objekte zusammen, deshalb immer 2 Objekte pro Zeile.
	int row = result/2;

	if(result % 2 == 0)
	{
		if(item_vector.at(row).name() != item->text().toStdString())
		{
			item_vector.at(row).name(item->text().toStdString());
			m_dataBase.putItem(item_vector.at(row));
		}
	}
	else
	{
		if(item_vector.at(row).description() != item->text().toStdString())
		{
			item_vector.at(row).description(item->text().toStdString());
			m_dataBase.putItem(item_vector.at(row));
		}
	}
}

void DataWidget::deleteAllTableItems()
{
	int size = m_tableItems.size();
	for(int counter = 0; counter < size; counter++)
	{
		QTableWidgetItem *item = m_tableItems.at(counter);
		delete item;
	}
	m_tableItems.clear();

	size = m_tableCombos.size();
	for(int counter = 0; counter < size; counter++)
	{
		QComboBox *box = m_tableCombos.at(counter);
		delete box;
	}
	m_tableCombos.clear();
}

void DataWidget::show()
{
	QWidget::show();

	Config* m_config = Config::getInstance();

	QString string(m_config->unit().c_str());
	lbl_unit.setText(string);

	string = m_config->subunit().c_str();
	lbl_subunit.setText(string);

	nameActionButtons();


    m_dataBase.openNewDatabase( Config::getInstance()->dbname());

    m_dataBase.getAllUnits( unit_vector );

    cmb_unit.clear();
    if(unit_vector.size() > 0)
    {
        for(std::vector<Unit>::iterator it = unit_vector.begin(); it != unit_vector.end(); ++it)
        {
            cmb_unit.addItem((it->name()).c_str());
        }
    }

    unitActivated();
	//refreshTable();
}

void DataWidget::comboChanged()
{
	//Die wievielte ComboBox wurde geändert?
	QComboBox *box;
	QComboBox *changedBox;
	int result = -1;
	for(int counter = 0; counter < m_tableCombos.size(); counter++)
	{
		box = m_tableCombos.at(counter);
		if(box->hasFocus() == true)
		{
			result = counter;
			changedBox = box;
		}
	}

	if(result != -1)
	{
		if(changedBox->currentIndex() == 0)
		{
			item_vector.at(result).used(1);
			m_dataBase.putItem(item_vector.at(result));
		}
		else
		{
			item_vector.at(result).used(0);
			m_dataBase.putItem(item_vector.at(result));
		}
	}
}

void DataWidget::refreshTable()
{
	deleteAllTableItems();
	subunitActivated();
}

void DataWidget::chkInuseChanged(int state)
{
	if(state == Qt::Unchecked)
	{
		if(m_intListMode == bothChecked)
		{
			m_intListMode = unusedChecked;
		}
		else if(m_intListMode == usedChecked)
		{
			m_intListMode = nothingChecked;
		}
	}
	else
	{
		if(m_intListMode == unusedChecked)
		{
			m_intListMode = bothChecked;
		}
		else if(m_intListMode == nothingChecked)
		{
			m_intListMode = usedChecked;
		}
	}

	refreshTable();
}

void DataWidget::chkNotinuseChanged(int state)
{
	if(state == Qt::Unchecked)
	{
		if(m_intListMode == bothChecked)
		{
			m_intListMode = usedChecked;
		}
		else if(m_intListMode == unusedChecked)
		{
			m_intListMode = nothingChecked;
		}
	}
	else
	{
		if(m_intListMode == usedChecked)
		{
			m_intListMode = bothChecked;
		}
		else if(m_intListMode == nothingChecked)
		{
			m_intListMode = unusedChecked;
		}
	}

	refreshTable();
}

void DataWidget::nameActionButtons()
{
	Config* m_config = Config::getInstance();
	QString string;

	string = m_config->unit().c_str();
	string.append(QString::fromUtf8(" hinzufügen"));
	btn_newUnit.setText(string);

	string = m_config->unit().c_str();
	string.append(QString::fromUtf8(" löschen"));
	btn_deleteUnit.setText(string);

	string = m_config->subunit().c_str();
	string.append(QString::fromUtf8(" hinzufügen"));
	btn_newSubunit.setText(string);

	string = m_config->subunit().c_str();
	string.append(QString::fromUtf8(" löschen"));
	btn_deleteSubunit.setText(string);

	string = m_config->item().c_str();
	string.append(QString::fromUtf8(" löschen"));
	btn_deleteItem.setText(string);

	string = "Neuer ";
	string.append(m_config->unit().c_str());
	string.append(" Name:");
	newUnitDialog.setMessage(string);

	string = "Neuer ";
	string.append(m_config->subunit().c_str());
	string.append(" Name:");
	newSubunitDialog.setMessage(string);
}

void DataWidget::addUnit()
{
	newUnitDialog.show();
}

void DataWidget::deleteUnit()
{
	m_dataBase.getAllUnits(unit_vector);

	if(cmb_unit.count() > 0 && unit_vector.size() > 0)
	{
		int currentIndex = cmb_unit.currentIndex();
		m_dataBase.deleteUnit(unit_vector.at(currentIndex).id());
		cmb_unit.removeItem(currentIndex);

		if(cmb_unit.currentIndex() != -1)
		{
			m_dataBase.getAllSubunits(subunit_vector, unit_vector.at(cmb_unit.currentIndex()).id());

			try
			{
				m_dataBase.getAllItems(item_vector, subunit_vector.at(cmb_subunit.currentIndex()).id());
			}
			catch(std::exception)
			{
				subunit_vector.clear();
			}
		}
		else
		{
			unit_vector.clear();
			subunit_vector.clear();
		}

		refreshTable();
	}

	unitActivated();
}

void DataWidget::addSubunit()
{
	newSubunitDialog.show();
}

void DataWidget::deleteSubunit()
{
	if(cmb_subunit.count() > 0 && subunit_vector.size() > 0)
	{
		int currentIndex = cmb_subunit.currentIndex();
		m_dataBase.deleteSubunit(subunit_vector.at(currentIndex).id());
		cmb_subunit.removeItem(currentIndex);

		if(cmb_subunit.currentIndex() != -1)
		{
			m_dataBase.getAllSubunits(subunit_vector, unit_vector.at(cmb_unit.currentIndex()).id());
			m_dataBase.getAllItems(item_vector, subunit_vector.at(cmb_subunit.currentIndex()).id());
		}
		else
		{
			subunit_vector.clear();
		}

		refreshTable();
	}
}

void DataWidget::deleteItem()
{
	int currentRow = tbl_items.currentRow();

	if(currentRow != -1)
	{
		m_dataBase.deleteItem(item_vector.at(currentRow).id());
	}

	refreshTable();
}

void DataWidget::filterItemVector()
{
	try
	{
		if(subunit_vector.size() > 0)
		{
			if(m_intListMode == bothChecked)
			{
				m_dataBase.getAllItems(item_vector, subunit_vector.at(cmb_subunit.currentIndex()).id());
			}
			else if(m_intListMode == unusedChecked)
			{
				m_dataBase.getAllItems(item_vector, subunit_vector.at(cmb_subunit.currentIndex()).id(), false);
			}
			else if(m_intListMode == usedChecked)
			{
				m_dataBase.getAllItems(item_vector, subunit_vector.at(cmb_subunit.currentIndex()).id(), true);
			}
			else
			{
				item_vector.clear();
			}
		}
	}
	catch(std::exception)
	{
	}
}

void DataWidget::appendUnit()
{
	std::string input = newUnitDialog.getInput().toStdString();
	std::string empty = "";
	Unit newUnit(-1, input, empty);

	m_dataBase.putUnit(newUnit);

	m_dataBase.getAllUnits(unit_vector);

	updateUnitCombo(false);
	cmb_unit.setCurrentIndex(cmb_unit.count() - 1);
}

void DataWidget::appendSubunit()
{
	std::string input = newSubunitDialog.getInput().toStdString();
	QString input_qt = newSubunitDialog.getInput();
	std::string empty = "";
	Subunit newSubunit(-1, unit_vector.at(cmb_unit.currentIndex()).id(), -1, input, empty);

	m_dataBase.putSubunit(newSubunit);

	m_dataBase.getAllSubunits(subunit_vector, unit_vector.at(cmb_unit.currentIndex()).id());

	//Aktualisieren der Subunit Combobox
	unitActivated();
	cmb_subunit.setCurrentIndex(cmb_subunit.count() - 1);
}

void DataWidget::updateUnitCombo(bool startAtFirst)
{
	cmb_unit.clear();

	if(unit_vector.size() > 0)
    {
        for(std::vector<Unit>::iterator it = unit_vector.begin(); it != unit_vector.end(); ++it)
        {
            cmb_unit.addItem(it->name().c_str());
        }

		if(startAtFirst == false)
		{
			cmb_unit.setCurrentIndex(cmb_unit.count() - 1);
		}

        unitActivated();
    }
}

void DataWidget::addNewDatabase(QString filename)
{
	m_dataBase.createNewDatabase(filename.toStdString());
}

} // namespace verema
